package top.xunfong.redis.aspet;

import cn.hutool.core.util.StrUtil;
import top.xunfong.redis.annotation.RedisLockAnnotation;
import top.xunfong.redis.expressionEvaluator.KeyExpressionEvaluator;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class RedisLockAspect {

    @Autowired
    private RedissonClient redissonClient;
    private final KeyExpressionEvaluator keyExpressionEvaluator = new KeyExpressionEvaluator();

    @Around("@annotation(redisLockAnnotation)")
    public Object around(ProceedingJoinPoint joinPoint, RedisLockAnnotation redisLockAnnotation) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String lockKey = StrUtil.toString(keyExpressionEvaluator.evaluate(method, joinPoint.getArgs(), redisLockAnnotation.key()));
//        String lockValue = UUID.randomUUID().toString();
//        long timeout = redisLockAnnotation.timeout();
        // 获取锁
        // 使用redisson获取锁, 使用redisson的看门狗
        RLock lock = redissonClient.getLock(lockKey);
        if (Boolean.TRUE.equals(lock.tryLock())) {
            try {
                // 获取到锁，执行方法
                return joinPoint.proceed();
            } finally {
                // 释放锁
                lock.unlock();
            }
        }
        return null;
    }
}
